<?php
/**
 * +----------------------------------------------------------------------
 * | Copyright © Sogu Technologies Co. Ltd 2018-2050 All rights reserved.
 * +----------------------------------------------------------------------
 * | File name: Sign.php
 * +----------------------------------------------------------------------
 * | Author: sam
 * +----------------------------------------------------------------------
 * | Description: RSA签名方法
 * +----------------------------------------------------------------------
 * | Others: 其他内容的说明
 * +----------------------------------------------------------------------
 * | History: 修改历史记录列表，每条修改记录应包含修改日期、修改者及修改内容简述
 * +----------------------------------------------------------------------
 * | 1.Date: 2018/12/26 Author: sam Modification: 创建
 * +----------------------------------------------------------------------
 */

namespace App\Library\Guzzle;


use App\Constant\Compatible;
use App\Exceptions\GeneralException;
use App\Library\ArrayTools\ArrayTools;
use App\Models\RepaySummary;
use Illuminate\Support\Facades\Log;
use Key\Rong360;

class Sign
{
    CONST TYPE_REFLECTION = [1 => 'common', 2 => 'money'];
    /**
     * Description:
     * Author: Sam
     * DateTime: 2018/12/27 10:26
     * @param $data
     * @param $type
     * @param $use_type int 1 => 使用新商户,2 => 使用旧商户
     * @return string
     * @throws GeneralException
     */
    public static function sign($data, $type,$use_type = RepaySummary::DATA_TYPE_ONE)
    {
        if($use_type == RepaySummary::DATA_TYPE_ONE){
            $pri_key_file = dirname(dirname(dirname(__DIR__))) . '/privateKey/' . self::TYPE_REFLECTION[$type] . '.pem';
        }else if($use_type == RepaySummary::DATA_TYPE_TWO){
            $pri_key_file = dirname(dirname(dirname(__DIR__))) . '/privateKey/compatible/' . self::TYPE_REFLECTION[$type] . '.pem';
        }else{
            Log::debug('签名:' . $type . ',' . $use_type);
            return 'aaa';
        }
        if (!file_exists($pri_key_file)) {
            throw new GeneralException('私钥文件不存在');
        };
        $priKey = file_get_contents($pri_key_file);
        $priKey = wordwrap($priKey, 64, "\n", true);
        $res = openssl_get_privatekey($priKey);
//        ksort($data);
        ArrayTools::recursive_key_sort($data);
        $str = json_encode($data,JSON_UNESCAPED_UNICODE);
        openssl_sign($str, $sign, $res);
        openssl_free_key($res);
        $sign = base64_encode($sign);
        return $sign;
    }

    /**
     * 小黑鱼验签
     * @param array $data
     * @param $sign
     * @return int
     * @author luwei
     * @date 2019-02-13 16:44
     */
    static function verify(array $data, $sign)  {
        $publicKey = dirname(dirname(dirname(__DIR__))) . '/privateKey/publicKey/' . 'fish.pem';
        $pubKey = file_get_contents($publicKey);
        $res = openssl_get_publickey($pubKey);
        $data = http_build_query($data);
        $result = openssl_verify($data, base64_decode($sign), $res,OPENSSL_ALGO_MD5);
        openssl_free_key($res);
        return $result;
    }

    /**
     * 小黑鱼验签
     * @param array $data
     * @param $sign
     * @return int
     * @author luwei
     * @date 2019-02-13 16:44
     */
    static function verifyPush(array $data, $sign)  {
        $publicKey = dirname(dirname(dirname(__DIR__))) . '/privateKey/publicKey/' . 'fish.pem';
        $pubKey = file_get_contents($publicKey);
        $res = openssl_get_publickey($pubKey);
        ArrayTools::recursive_key_sort($data);
        $data = http_build_query($data);
        $data = urldecode($data);
        $result = openssl_verify($data, base64_decode($sign), $res,OPENSSL_ALGO_MD5);
        openssl_free_key($res);
        return $result;
    }

    /**
     * 小黑鱼签名
     * @param $data
     * @return string
     * @throws GeneralException
     * @author luwei
     * @date 2019-02-13 17:43
     */
    public static function signForFish($data){
        $pri_key_file = dirname(dirname(dirname(__DIR__))) . '/privateKey/' . 'fish.pem';
        if (!file_exists($pri_key_file)) {
            throw new GeneralException('私钥文件不存在');
        };
        $priKey = file_get_contents($pri_key_file);
        $res = openssl_get_privatekey($priKey);
        $str = http_build_query($data);
        openssl_sign($str, $sign, $res, OPENSSL_ALGO_MD5);
        openssl_free_key($res);
        $sign = base64_encode($sign);
        return $sign;
    }

    /**
     * 融360机构签名
     * @param $data
     * @return string
     * @throws GeneralException
     * @author luwei
     * @date 2019-02-13 17:43
     */
    public static function signForClient($data){
        $pri_key_file = dirname(dirname(dirname(__DIR__))) . '/privateKey/rong360/' . 'org_private.pem';

        if (!file_exists($pri_key_file)) {
            throw new GeneralException('私钥文件不存在');
        };
        $priKey = file_get_contents($pri_key_file);
        $res = openssl_get_privatekey($priKey);
        $str = self::getSignContent($data);
        openssl_sign($str, $sign, $res);
        $sign = base64_encode($sign);
        openssl_free_key($res);
        return $sign;
    }

    /**
     * 获取签名前元数据
     * @param $params
     * @return string
     * @author luwei
     * @date 2019-02-21 17:02
     */
    protected static function getSignContent($params) {
        ksort($params);
        $i                = 0;
        $stringToBeSigned = "";
        foreach ($params as $k => $v) {
            if ($i == 0) {
                $stringToBeSigned .= "$k" . "=" . "$v";
            } else {
                $stringToBeSigned .= "&" . "$k" . "=" . "$v";
            }
            $i++;
        }
        unset ($k, $v);
        return $stringToBeSigned;
    }

    /**
<<<<<<< HEAD
     * rong360机构验签   目前无法用  对方提供验签方式有问题！！！
     * @param $data
     * @param $sign
     * @return int
     * @author luwei
     * @date 2019-02-13 16:44
     * @throws GeneralException
     */
    static function verifyForClient($data, $sign)  {
        $pub_key_file = dirname(dirname(dirname(__DIR__))) . '/privateKey/rong360/' . 'org_public.pem';
        if (!file_exists($pub_key_file)) {
            throw new GeneralException('公钥文件不存在');
        };
        $pubKey = file_get_contents($pub_key_file);
        $res = openssl_get_publickey($pubKey);
        $result = openssl_verify($data, base64_decode($sign), $res);
        openssl_free_key($res);
        return $result;
    }

    /**
     * rong360验签
     * @param $data json格式
     * @param $sign
     * @return int
     * @author luwei
     * @date 2019-02-13 16:44
     * @throws GeneralException
     */
    static function verifyForServer($data, $sign)  {
        $pub_key_file = dirname(dirname(dirname(__DIR__))) . '/privateKey/rong360/' . 'rong_public.pem';
        if (!file_exists($pub_key_file)) {
            throw new GeneralException('公钥文件不存在');
        };
        $pubKey = file_get_contents($pub_key_file);
        $res = openssl_get_publickey($pubKey);
        $result = openssl_verify($data, base64_decode($sign), $res,OPENSSL_ALGO_SHA256);
        openssl_free_key($res);
        return $result;
    }
    /**
     * Description:对催收进行加密
     * Author:lijiafei
     * @param array $data
     * @return string
     * @throws GeneralException
     */
    public static function collectionSign(array $data){
        $pri_key_file = dirname(dirname(dirname(__DIR__))) . '/privateKey/collection/'  . 'collection.pem';
        if (!file_exists($pri_key_file)) {
            throw new GeneralException('私钥文件不存在');
        };
        $priKey = file_get_contents($pri_key_file);
        $res = openssl_get_privatekey($priKey);
//        ksort($data);
//        ArrayTools::recursive_key_sort($data);
        $str = json_encode($data,JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
        openssl_sign($str, $sign, $res);
        openssl_free_key($res);
        $sign = base64_encode($sign);
        return $sign;
    }

}